﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

using Segmentation.Business;
using Segmentation.Business.Criterions;


namespace Segmentation.Test
{
    class Program
    {
		#region Consts 

        const int width = 256;
        const int height = 128;

		#endregion Consts 

		#region Methods 

        private static void BatchModelImage()
        {
            //double[] psnrs = new double[] { 100, 50, 20, 15, 10, 7, 5, 3, 2, 1 };
            double[] psnrs = new double[] { 20, 15, 13, 10, 7, 5, 3, 1 };
            JSEGAccessor.Mode[] modes = new JSEGAccessor.Mode[] { 
                JSEGAccessor.Mode.Original, 
                JSEGAccessor.Mode.JModification1,
                JSEGAccessor.Mode.JModification2,
                JSEGAccessor.Mode.JModification3};

            CriterionTest test = new CriterionTest(modes, psnrs);

            test.Process();
        }

        static void Main(string[] args)
        {
            if (args.Length == 1)
            {
                ProcessInputFile(args[0]);
            }
            else
            {
                ProcessModelImage();
                
                BatchModelImage();
            }
        }

        private static void ProcessInputFile(string imagePath)
        {
            if (File.Exists(imagePath))
            {
                Bitmap inputImage = Bitmap.FromFile(imagePath) as Bitmap;
                if (inputImage != null)
                {
                    ImageContainer image = new ImageContainer(inputImage);

                    image.Segment(JSEGAccessor.Mode.Original);
                    SaveImages(image, "O_");

                    image.Segment(JSEGAccessor.Mode.JModification1);
                    SaveImages(image, "M1_");


                    image.Segment(JSEGAccessor.Mode.JModification2);
                    SaveImages(image, "M2_");


                    image.Segment(JSEGAccessor.Mode.JModification3);
                    SaveImages(image, "M3_");                   
                }
                else
                {
                    Console.WriteLine("Input file isn't image.");
                }
            }
            else
            {
                Console.WriteLine("Cannot find input file.");
            }
        }

        private static void ProcessModelImage()
        {
            string dirResults = Path.Combine(Environment.CurrentDirectory, @"Results\");
            CreateDirIfNotExist(dirResults);
            Environment.CurrentDirectory = dirResults;

            ModelImage model = ModelImage.Create(width, height, Color.Red, Color.Green);
            model.Bitmap.Save("model.bmp", ImageFormat.Bmp);

            //model.AddNoise(10);
            //model.Bitmap.Save("noised.bmp", ImageFormat.Bmp);
            
            int range = width / 8 - 16;

            StreamWriter jsw = new StreamWriter("JValues.csv", true);
            jsw.Write("Pixels;");
            for (int x = width / 2 - range; x < width / 2 + range; x++)
            {
                jsw.Write(string.Format("{0};", x));
            }
            jsw.WriteLine();
            jsw.Close();

            model.Segment(JSEGAccessor.Mode.Original);
            SaveImages(model, "O_"); 
            
            
            model.Segment(JSEGAccessor.Mode.JModification1);
            SaveImages(model, "M1_"); 
            
            
            model.Segment(JSEGAccessor.Mode.JModification2);
            SaveImages(model, "M2_"); 
            

            model.Segment(JSEGAccessor.Mode.JModification3);
            SaveImages(model, "M3_");
        }

        private static void SaveImages(ImageContainer model, string ind)
        {
            //BitmapCreater.GetBitmapFromMap(model.JSEGAccessor.ColorMap).Save(ind + "cmap.bmp", ImageFormat.Bmp);
            BitmapCreater.GetBitmapFromMap(model.JSEGAccessor.RegionMap).Save(ind + "rmap.bmp", ImageFormat.Bmp);
            BitmapCreater.GetBitmapWithBounderies(model.JSEGAccessor.RegionMap, model.Bitmap, 0.5).Save(ind + "bounderies.bmp", ImageFormat.Bmp);

            //SaveJValues(model.JSEGAccessor.JImages, ind);
        }

        private static void SaveJValues(JImage[] jimages, string ind)
        {
            int y = height / 2;
            int range = width / 8 - 16;

            StreamWriter jsw = new StreamWriter("JValues.csv", true);
            for (int i = 0; i < jimages.Length; i++ )
            {
                if (i != 0 && i != 1)
                {
                    continue;
                }
                JImage jImage = jimages[i];
                //BitmapCreater.GetBitmapFromJ(jImage.JData).Save(string.Format("{1}{0}.bmp", jImage.ToString(), ind), ImageFormat.Bmp);

                /*
                jsw.Write(string.Format("{1}{0};", jImage.ToString(), ind));
                for (int x = jImage.JData.GetLength(1) / 2 - range; x < jImage.JData.GetLength(1) / 2 + range; x++)
                {
                    jsw.Write(string.Format("{0};", jImage.JData[y, x]));
                }
                */

                jsw.Write(string.Format("Norm_{1}{0};", jImage.ToString(), ind));
                double max = jImage.JData[y, jImage.JData.GetLength(1) / 2 - range];
                for (int x = jImage.JData.GetLength(1) / 2 - range; x < jImage.JData.GetLength(1) / 2 + range; x++)
                {
                    if (jImage.JData[y, x] > max)
                    {
                        max = jImage.JData[y, x];
                    }
                }

                int effLenght = 0;
                for (int x = jImage.JData.GetLength(1) / 2 - range; x < jImage.JData.GetLength(1) / 2 + range; x++)
                {
                    double j = jImage.JData[y, x] / max;
                    jsw.Write(string.Format("{0};", j));

                    if (j > 0.5)
                    {
                        effLenght++;
                    }
                }
                jsw.Write(string.Format(";{0};", effLenght));
                jsw.WriteLine();

            }
            jsw.Close();
        }

        private static void CreateDirIfNotExist(string dirName)
        {
            if (Directory.Exists(dirName))
            {
                try
                {
                    Directory.Delete(dirName, true);
                }
                catch { }
            }
            try
            {
                Directory.CreateDirectory(dirName);
            }
            catch { }
        }

		#endregion Methods 
    }
}
